package org

import (
    "time"
	"strings"
	"strconv"
	"dhfshop/utils/helper"
	"dhfshop/models/org"
	"dhfshop/controllers/base"
	//"github.com/astaxie/beego"
	"github.com/astaxie/beego/validation"
	//jwt "github.com/dgrijalva/jwt-go"
	//"dhfshop/service/wechat"
)

type AuthorizeController struct {
	base.BaseController
}
/*
func (this *AuthorizeController) GetAuthInfo() {
    var (
		curAuthUser *org.AuthenticatedUser = new(org.AuthenticatedUser)
	)
	v := struct {
	    Code           string   `form:"code" valid:"Required"`
		EncryptedData  string   `form:"encryptedData" valid:"Required"`
		Iv             string   `form:"iv" valid:"Required"`
		IdentityId     string   `form:"identity_id"`
		IsAdmin        bool     `form:"is_admin"`
	}{} 
	this.ParseForm(&v)
	valid := validation.Validation{}
	passed, _ := valid.Valid(&v)
	if !passed {
		this.ServeError(valid.Errors[0].Key+" "+valid.Errors[0].Message)
		return 
	}
	appId := beego.AppConfig.String("SellerAppID")
	appSecret := beego.AppConfig.String("SellerAppSecret")
	weUser, err := wechat.AppletSellerLogin(appId, appSecret, v.Code, v.EncryptedData, v.Iv)
	if err != nil{
		this.ServeError(err.Error())
		return
	}
	if !v.IsAdmin {
		this.Data["json"] = map[string]string{
		   "open_id": weUser.OpenID,
	    }
		this.ServeJSON()
		return
	}
	if user, err := org.GetUserIdByOpenId(weUser.OpenID); err == nil {
		user.SessionKey = weUser.SessionKey
		org.UpdateUsersById(user, "session_key")    //更新: session_key
		for _, roleIdStr := range strings.Split(user.RoleIds, ",") {
			roleId, _:= strconv.ParseInt(roleIdStr, 10, 64)
			if role, err := org.GetPartnerIdByRoleId(roleId); err == nil {
				if role.IsSuperAdmin {
				    curAuthUser.PartnerId = role.PartnerId
					curAuthUser.Admin = role.IsSuperAdmin
					curAuthUser.UserId = user.UserId
				    break
				}
			}
		}
	}
	token := jwt.New(jwt.GetSigningMethod("HS256"))
	claims := token.Claims.(jwt.MapClaims)
	claims["CurrentUser"] = struct {
	    Id int
		CompanyId int
		Role int
	}{Id: int(curAuthUser.UserId), CompanyId: int(curAuthUser.PartnerId), Role: 2}
	claims["exp"] = time.Now().UTC().Add(time.Hour * 24 * 1).Unix()
	tokenSecret := beego.AppConfig.String("AuthTokenSecret")
	tokenString, err := token.SignedString([]byte(tokenSecret))
	if err != nil {
		this.ServeError("登录失败，请稍后再试")
		return
	}
	this.Data["json"] = map[string]string{
	    "user_id": strconv.FormatInt(curAuthUser.UserId, 10),
		"partner_id": strconv.FormatInt(curAuthUser.PartnerId, 10),
		"token": tokenString,
	}
	this.ServeJSON()
}
*/

func (this *AuthorizeController) Bind() {
    v := struct {
		OpenId     string   `form:"open_id" valid:"Required"`
		RoleId     int64    `form:"role_id" valid:"Required"`
	}{} 
	this.ParseForm(&v)
	valid := validation.Validation{}
	passed, _ := valid.Valid(&v)
	if !passed {
		this.ServeError(valid.Errors[0].Key+" "+valid.Errors[0].Message)
		return 
	}
	partnerId := int64(this.Ctx.Input.GetData("curCompanyId").(int))
	curUserId := int64(this.Ctx.Input.GetData("curUserId").(int))
	if partnerId == 0 {
		this.ServeError("user is not login")
	    return
	}
	user, err := org.GetUserIdByOpenId(v.OpenId)
	if err != nil {
	    this.ServeError(err.Error())
	    return
	}
	partnerIdArr := []string{}
	roleIdArr := strings.Split(user.RoleIds, ",")
	for _, roleIdStr := range roleIdArr {
	    roleId, _:= strconv.ParseInt(roleIdStr, 10, 64)
		if role, err := org.GetPartnerIdByRoleId(roleId); err == nil {
			partnerIdArr = append(partnerIdArr, strconv.FormatInt(role.PartnerId, 10))
		}  
	}
	dstRole, err := org.GetRoleByRoleId(v.RoleId)
	if err != nil {
	    this.ServeError(err.Error())
	    return
	}
	//限制一个人在同一个组织中同时具有多个角色
	partnerIdStr := strconv.FormatInt(dstRole.PartnerId, 10)
	if _, err := helper.Contains(partnerIdStr, partnerIdArr); err == nil {
	    this.ServeError("用户在同一组织只能绑定一个角色,需要先解除旧角色绑定,再绑定新角色")
	    return
	}
	if _, err := helper.Contains(strconv.FormatInt(v.RoleId, 10), roleIdArr); err != nil {
	    roleIdArr = append(roleIdArr, strconv.FormatInt(v.RoleId, 10))
	}
	user.RoleIds = strings.Join(roleIdArr, ",")
	user.RoleIds = strings.Trim(user.RoleIds, ",")
	if err := org.UpdateUsersById(user, "role_ids"); err != nil {
	    this.ServeError(err.Error())
	    return
	}
	rsp := struct {
		UserId    int64         `json:"user_id"`
	    Modified  time.Time   `json:"modified"`
	}{UserId:curUserId, Modified:time.Now().UTC()}
	this.Data["json"] = rsp
	this.ServeJSON()
}

func (this *AuthorizeController) UnBind() {
     v := struct {
		OpenId     string   `form:"open_id" valid:"Required"`
		RoleId     int64    `form:"role_id" valid:"Required"`
	}{} 
	this.ParseForm(&v)
	valid := validation.Validation{}
	passed, _ := valid.Valid(&v)
	if !passed {
		this.ServeError(valid.Errors[0].Key+" "+valid.Errors[0].Message)
		return 
	}
	partnerId := int64(this.Ctx.Input.GetData("curCompanyId").(int))
	curUserId := int64(this.Ctx.Input.GetData("curUserId").(int))
	if partnerId == 0 {
		this.ServeError("user is not login")
	    return
	}
	_, err := org.GetRoleByRoleId(v.RoleId)
	if err != nil {
	    this.ServeError(err.Error())
	    return
	}
	user, err := org.GetUserIdByOpenId(v.OpenId)
	if err != nil {
	    this.ServeError(err.Error())
	    return
	}
	roleIdStr := strconv.FormatInt(v.RoleId, 10)
	roleIdArr := strings.Split(user.RoleIds, ",")
	if ok, err := helper.Contains(roleIdStr, roleIdArr); ok && err == nil {
	    roleIdArr = helper.Remove(roleIdArr, roleIdStr)
	}
	user.RoleIds = strings.Join(roleIdArr, ",")
	if err := org.UpdateUsersById(user, "role_ids"); err != nil {
	    this.ServeError(err.Error())
	    return
	}
	rsp := struct {
		UserId    int64         `json:"user_id"`
	    Modified  time.Time   `json:"modified"`
	}{UserId:curUserId, Modified:time.Now().UTC()}
	this.Data["json"] = rsp
	this.ServeJSON()
}
